﻿using System;
using System.Windows.Controls;
using System.Windows;
using System.Collections.Generic;

namespace WickedFlame.GenDock
{
    public class LayoutPanel : Panel
    {
        /// <summary>
        /// Gets or sets the orientation of the panel
        /// </summary>
        /// <remarks>If horizontal oriented children are positioned from left to right and width of each child is computed according to <see cref="ResizingWidth"/> attached property value. When vertical oriented children are arranged from top to bottom, according to <see cref="ResizingHeight"/> of each child.</remarks>
        public Orientation Orientation
        {
            get { return (Orientation)GetValue(OrientationProperty); }
            set { SetValue(OrientationProperty, value); }
        }

        /// <summary>
        /// Give access to Orientation attached property
        /// </summary>
        /// <remarks>If horizontal oriented children are positioned from left to right and width of each child is computed according to <see cref="ResizingWidth"/> attached property value. When vertical oriented children are arranged from top to bottom, according to <see cref="ResizingHeight"/> of each child.</remarks>
        public static readonly DependencyProperty OrientationProperty =
            DependencyProperty.Register("Orientation", typeof(Orientation), typeof(LayoutPanel), new FrameworkPropertyMetadata(Orientation.Horizontal, FrameworkPropertyMetadataOptions.AffectsMeasure, OnOrientationChanged));

        static void OnOrientationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            //((LayoutPanel)d).splitterListIsDirty = true;
        }

        //bool splitterListIsDirty = false;

        //private TimeSpan _AnimationLength = TimeSpan.FromMilliseconds(200);
        /// <summary>
        /// Arranges children giving them a proportional space
        /// </summary>
        /// <param name="finalSize"></param>
        /// <returns></returns>
        protected override Size ArrangeOverride(Size finalSize)
        {
            List<FrameworkElement> visibleChildren = new List<FrameworkElement>();

            int anchorCount = 0;
            double anchorWidth = 0.0;

            for (int i = 0; i < VisualChildrenCount; i++)
            {
                FrameworkElement child = GetVisualChild(i) as FrameworkElement;
                child.Measure(finalSize);
                visibleChildren.Add(child);

                if (child is Anchor)
                {
                    anchorCount++;
                    anchorWidth += child.DesiredSize.Width;
                }
            }

            
            double xpos = 0.0;

            double widthTmp = 0.0;
            for (int i = 0; i < visibleChildren.Count;i++ )
            {
                FrameworkElement child = visibleChildren[i];
                if (child is Anchor)
                {
                    //child.MinHeight = finalSize.Height;
                    //child.MinWidth = 50;

                    child.Height = finalSize.Height;
                    //child.Width = child.MinWidth;
                    //if (double.IsNaN(child.Width))

                    widthTmp = child.DesiredSize.Width;
                    //child.Arrange(new Rect(xpos, 0.0, child.Width, child.Height));
                    child.Arrange(new Rect(xpos, 0.0, child.DesiredSize.Width, child.Height));

                    //width += child.DesiredSize.Width; ;// child.Width;
                    
                }
                else
                {
                    child.Width = ((finalSize.Width - anchorWidth) / (visibleChildren.Count - anchorCount));
                    child.Height = finalSize.Height;
                    child.Arrange(new Rect(xpos, 0.0, child.Width, child.Height));

                    widthTmp = child.Width;
                }
                xpos += widthTmp;// child.Width;
            }

            return base.ArrangeOverride(finalSize);

            //Point point = new Point(0, 0);
            //int i = 0;

            //if (Orientation == Orientation.Horizontal)
            //{
            //    double largestHeight = 0.0;

            //    foreach (UIElement child in Children)
            //    {
            //        //child.Arrange(new Rect(point, new Point(point.X +
            //        //  child.DesiredSize.Width, point.Y + child.DesiredSize.Height)));

            //        if (child.DesiredSize.Height > largestHeight)
            //            largestHeight = child.DesiredSize.Height;

            //        point.X = point.X + child.DesiredSize.Width;

            //        if ((i + 1) < Children.Count)
            //        {
            //            if ((point.X + Children[i + 1].DesiredSize.Width) > finalSize.Width)
            //            {
            //                point.X = 0;
            //                point.Y = point.Y + largestHeight;
            //                largestHeight = 0.0;
            //            }
            //        }
            //        i++;
            //    }
            //}
            //else
            //{
            //    double largestWidth = 0.0;

            //    foreach (UIElement child in Children)
            //    {
            //        child.Arrange(new Rect(point, new Point(point.X +
            //          child.DesiredSize.Width, point.Y + child.DesiredSize.Height)));

            //        if (child.DesiredSize.Width > largestWidth)
            //            largestWidth = child.DesiredSize.Width;

            //        point.Y = point.Y + child.DesiredSize.Height;

            //        if ((i + 1) < Children.Count)
            //        {
            //            if ((point.Y + Children[i + 1].DesiredSize.Height) > finalSize.Height)
            //            {
            //                point.Y = 0;
            //                point.X = point.X + largestWidth;
            //                largestWidth = 0.0;
            //            }
            //        }

            //        i++;
            //    }
            //}

            //return base.ArrangeOverride(finalSize);
        }

        /// <summary>
        /// Compute the desidered size of the panel
        /// </summary>
        /// <param name="availableSize"></param>
        /// <returns></returns>
        protected override Size MeasureOverride(Size availableSize)
        {
            //List<FrameworkElement> visibleChildren = new List<FrameworkElement>();
            //for (int i = 0; i < VisualChildrenCount; i++)
            //{
            //    FrameworkElement child = GetVisualChild(i) as FrameworkElement;
            //    child.Measure(availableSize);
            //    visibleChildren.Add(child);
            //}

            //return base.MeasureOverride(availableSize);

            foreach (UIElement child in Children)
            {
                child.Measure(new Size(availableSize.Width, availableSize.Height));
            }

            //return base.MeasureOverride(availableSize);
            return base.MeasureOverride(new Size(0, 0));
        }
    }
}
